package blackstar.agent.jmx;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import blackstar.agent.security.SecurityUser;
import blackstar.agent.security.UserManager;

/**
 * @author RayWoo (ayufox@gmail.com)
 * 
 */
public class AgentJMXAuthenticator implements JMXAuthenticator
{
	private final static Log LOGGER = LogFactory
			.getLog(AgentJMXAuthenticator.class);
	private UserManager userManager;

	public AgentJMXAuthenticator(UserManager userManager)
	{
		this.userManager = userManager;
	}

	public Subject authenticate(Object credentials)
	{
		if (!(credentials instanceof String[]))
		{
			LOGGER.info("Bad credentials");
			throw new SecurityException("Bad credentials");
		}
		String[] creds = (String[]) credentials;
		if (creds.length != 2)
		{
			LOGGER.info("Bad credentials");
			throw new SecurityException("Bad credentials");
		}

		String user = creds[0];
		String password = creds[1];

		LOGGER.info("authenticate[user=" + user + "]");

		if (password == null)
		{
			LOGGER.info("Bad password");

			throw new SecurityException("Bad password");
		}

		SecurityUser securityUser = this.userManager.findUser(user);
		if (securityUser == null)
		{
			throw new SecurityException("Unknown user " + user);
		}

		if (!securityUser.authenticate(password))
		{
			throw new SecurityException("Bad password");
		}

		Set principals = new HashSet();
		principals.add(new JMXPrincipal(securityUser.getName()));
		return new Subject(true, principals, Collections.EMPTY_SET,
				Collections.EMPTY_SET);
	}
}